package com.johnzer.frame.utils;

import android.content.ClipboardManager;
import android.content.Context;
import android.text.Html;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.widget.TextView;


import com.johnzer.frame.app.BaseApp;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by johnzer on 2014/6/8.
 */
public class StringUtils {


    /**
     * InputStream转byte数组
     *
     * @param is
     * @return
     */
    public static byte[] stream2Byte(InputStream is) {

        byte[] in_b = null;
        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();

            int i = -1;
            while ((i = is.read()) != -1) {
                os.write(i);

            }

            in_b = os.toByteArray();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return in_b;

    }

    /**
     * InputStream 转String
     *
     * @param is
     * @return
     */
    public static String stream2String(InputStream is) {

        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            StringWriter sw = new StringWriter();
            int i = -1;
            while ((i = br.read()) != -1) {
                sw.write(i);
            }
            return sw.getBuffer().toString();
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;

    }

    /**
     * 字符串转InputStream
     *
     * @param str
     * @return
     */
    public static InputStream string2Stream(String str) {

        ByteArrayInputStream is = new ByteArrayInputStream(str.getBytes());

        return is;
    }

    /**
     * byte数组转InputStream
     *
     * @param by
     * @return
     */
    public static InputStream byte2Stream(byte[] by) {

        ByteArrayInputStream stream = new ByteArrayInputStream(by);

        return stream;
    }

    /**
     * 判断是否是中文字符,只能判断部分CJK字符
     *
     * @param str
     * @return
     */
    public static boolean isChina(String str) {
        Pattern p = Pattern.compile("[\\u4E00-\\u9FBF]+");
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 根据Unicode编码完美的判断中文汉字和符号
     *
     * @param c
     * @return
     */
    public static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }

    /**
     * 过滤emoji表情
     */
    public static String FilterEmoji(String source) {
        if (TextUtils.isEmpty(source))
            return null;
        String filterStr = source;
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint)) { // 如果不能匹配,则该字符是Emoji表情
                filterStr = filterStr.replace(codePoint + "", "");
                LogUtils.e("isEmojiCharacter :" + i);
            }
        }
        return filterStr;
    }

    /**
     * 检测是否有emoji表情
     */
    public static boolean containsEmoji(String source) {
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint)) { // 如果不能匹配,则该字符是Emoji表情
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否是Emoji @param codePoint 比较的单个字符
     */
    private static boolean isEmojiCharacter(char codePoint) {
        return !((codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
                || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)));
    }

    /**
     * 判断是否包含中文汉字
     *
     * @param strName
     * @return
     */
    public static boolean isChineseHave(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否包含中文汉字
     *
     * @param strName
     * @return
     */
    public static String chineseFilter(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                strName = strName.replace(c + "", "");
            }
        }
        return strName;
    }

    /**
     * 用户名只允许手机号与邮箱
     */
    public static String FilterUserName(String str) {
        String regEx = "[^[0-9a-zA-Z@._]]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }

    /**
     * 判断用户名是否合法
     */
    public static boolean isLegalUserName(String str) {
        String regEx = "^[a-zA-Z0-9@._]+$";// 字母开头，允许5-16字节，允许字母数字_@.
        // String regEx = "^[a-zA-Z][a-zA-Z0-9@._]$";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        LogUtils.e("isLegalUserName = " + m.matches());
        return m.matches();
    }

    /**
     * 密码数字字母下划线
     */
    public static String FilterPassWord(String str) {
        String regEx = "[^[0-9a-zA-Z_]]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }

    /**
     * 判断密码是否合法
     */
    public static boolean isLegalPassWord(String str) {
//	String regEx = "^[A-Za-z0-9_]+$";// 判断是否合法数组字母下划线
//	Pattern p = Pattern.compile(regEx);
//	Matcher m = p.matcher(str);
//	LogUtils.e("isLegalPassWord = " + m.matches());
//	return m.matches();
        // 暂时不使用正则判断
        return true;
    }

    /**
     * 正常输入过滤非法字符
     */
    public static String FilterIllegalChar(String str) {
        String regEx = "[\\s|\t|\r|\n]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();// 循环遍历,替换所有
    }

    /**
     * 判断正常输入是否合法
     */
    public static boolean isIllegalStr(String str) {
        if (containsEmoji(str)) {
            return true;
        }
        String regEx = "[\\s|\t|\r|\n]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.find();// 是否包含
    }

    /**
     * 判断是否只有中文汉字
     *
     * @param strName
     * @return
     */
    public static boolean isChineseAll(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (!isChinese(c)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断邮政编码
     *
     * @param str
     * @return
     */
    public static boolean isCard(String str) {
        Pattern p = Pattern.compile("[1-9]\\d{5}(?!\\d)");
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 检测邮箱合法性
     *
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {
        if ((email == null) || (email.trim().length() == 0)) {
            return false;
        }
        String regEx = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(email.trim().toLowerCase());

        return m.find();
    }

    /**
     * 检查手机号码合法性
     * <p>
     * "130", "131", "132","133", "134", "135", "136", "137", "138", "139",
     * "140", "145", "147", "149"
     * "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
     * "170", "173", "176", "177"
     * "180", "181", "182", "183", "184", "185", "186", "187", "188", "189"
     *
     * @param value
     * @return
     */
    public static boolean isPhoneNumber(String value) {
        if (isEmpty(value)) {
            return false;
        }
        return checkPhoneNumber(value);//boolean
    }

    private static boolean checkPhoneNumber(String value) {
        String regExp = "^([\\d\\+])?\\d{7,15}$";
        Pattern p = Pattern.compile(regExp);

        Matcher m = p.matcher(value);

        return m.find();//boolean
    }

    /**
     * 判断字符串中是否是整型数字
     *
     * @param str
     * @return
     */
    public static boolean isInt(String str) {
        if (!TextUtils.isEmpty(str)) {
            return str.toString().matches("^[-]?\\d+$");
        }

        return false;
    }

    /**
     * 字符串转整型
     *
     * @param str
     * @return
     */
    public static int getInt(String str) {
        if (!TextUtils.isEmpty(str)) {
            String newValue = str.toString().replaceAll("\\D+", "");
            if (!TextUtils.isEmpty(newValue)) {
                return 0;
            }
            return Integer.parseInt(newValue);
        }
        return 0;
    }

    /**
     * 判断字符串中是否是Double
     *
     * @param str
     * @return
     */
    public static boolean isDouble(String str) {
        if (!TextUtils.isEmpty(str)) {
            return str.toString().matches("^\\d+(\\.[\\d]+)?$");
        }
        return false;
    }

    /**
     * 字符串转Double
     *
     * @param str
     * @return
     */
    public static double getDouble(String str) {
        if (!TextUtils.isEmpty(str)) {
            if (isDouble(str))
                return Double.parseDouble(str);
            else
                return 0.0D;
        }
        return 0.0D;
    }

    /**
     * 字符串转Double,并进行四舍五入
     *
     * @param str
     * @param scale
     * @return
     */
    public static double getDouble(String str, int scale) {
        Double v = getDouble(str);

        return getDouble(v, scale);
    }

    /**
     * Double进行四舍五入
     *
     * @param v
     * @param scale
     * @return
     */
    public static double getDouble(Double v, int scale) {

        if (scale < 0) {
            scale = 0;
        }
        BigDecimal b = new BigDecimal(v);
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 得到指定位数的小数
     *
     * @param v
     * @param scale
     * @return
     */
    public static String getDecimals(Double v, int scale) {

        return String.format("%." + String.valueOf(scale) + "f", v);

    }

    /**
     * 得到指定位数的小数
     *
     * @param v
     * @param scale
     * @return
     */
    public static String getDecimals(String v, int scale) {

        return getDecimals(getDouble(v), scale);

    }

    /**
     * Java String操作获取给的字符之后的子串，containJiange = true，带间隔字符串
     */
    public static String getSubStringRight(String str, String jiange,
                                           boolean containJiange) {
        if ((str != null) && (str.length() > 0)) {
            int dot = str.lastIndexOf(jiange);
            if ((dot > -1) && (dot < (str.length()))) {
                if (containJiange) {
                    return str.substring(dot, str.length());
                } else {
                    return str.substring(dot + jiange.length(), str.length());
                }
            }
        }
        return str;
    }

    /**
     * Java String操作 获取给的字符之前的子串 ，containJiange = true，带间隔字符串
     */
    public static String getSubStringLeft(String str, String jiange,
                                          boolean containJiange) {
        if ((str != null) && (str.length() > 0)) {
            int dot = str.lastIndexOf(jiange);
            if ((dot > -1) && (dot < (str.length()))) {
                if (containJiange) {
                    return str.substring(0, dot + jiange.length());
                } else {
                    return str.substring(0, dot);
                }
            }
        }
        return str;
    }

    /**
     * Java String操作 获取給的开头和结尾的字符
     */
    public static String getSubString2(String str, String start, String end) {
        if ((str != null) && (str.length() > 0)) {
            int start1 = str.lastIndexOf(start);
            int end1 = str.lastIndexOf(end);
            if ((start1 > -1) && (start1 < (str.length()))
                    && (end1 <= (str.length()))) {
                return str.substring(start1 + 1, end1);
            }
        }
        return str;
    }

    /**
     * 将数据格式化为指定位数的 float 数据
     *
     * @param format 需要格式化的位数的字符串
     * @param f      需要被的数值
     * @return 格式化后的数值
     */
    public static String fomatFloat2String(String format, float f) {
        format = isEmpty(format) ? "%.2f" : format;
        String result = f + "";
        try {
            result = String.format(format, f);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 将数据格式化为指定位数的 float 数据
     *
     * @param format 需要格式化的位数的字符串
     * @param f      需要被的数值
     * @return 格式化后的数值
     */
    public static float fomatFloatValue(String format, float f) {
        format = isEmpty(format) ? "%.2f" : format;
        try {
            f = Float.parseFloat(String.format(format, f));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }


    /**
     * 将数据格式化为指定位数的 double型的数据
     *
     * @param format 需要格式化小数位数的字符串
     * @param d      需要被的数值
     * @return 格式化后的数值
     */
    public static double fomatDoubleValue(String format, double d) {
        format = isEmpty(format) ? "%.2f" : format;
        try {
            d = Float.parseFloat(String.format(format, d));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return d;
    }

    /**
     * 给一段文字加上缩进
     * @param detialDesc
     * @return
     */
    public static String dealDesc(String detialDesc) {
        // TODO Auto-generated method stub
        StringBuilder sb1 = new StringBuilder();
        String indentation = "\u3000\u3000";//缩进
        sb1.append(indentation);

        StringBuilder sb2 = new StringBuilder(detialDesc);
        Pattern p = Pattern.compile("\n");             //插入位置
        Matcher m = p.matcher(detialDesc);
        int start = 0;
        while (m.find(start)) {
            start = m.start() + 1;
            sb2.insert(start, "\n" + indentation);       //插入字符串
            m = p.matcher(sb2.toString());
            start += indentation.length();
        }
        sb1.append(sb2);
        return sb1.toString();
    }

    /**
     * 判断字符串是否有值，如果为null或者是空字符串或者只有空格或者为"null"字符串，则返回true，否则则返回false
     */
    public static boolean isEmpty(CharSequence value) {
        if (value != null && !"".equalsIgnoreCase(value.toString().trim()) && !"null".equalsIgnoreCase(value.toString().trim())) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 判断控件中的字符串是否有值，如果为null或者是空字符串或者只有空格或者为"null"字符串，则返回true，否则则返回false
     */
    public static boolean isEmpty(TextView tv) {
        return isEmpty(getTextStr(tv));
    }

    public static boolean isHttpUrl(String url){
        if (!isEmpty(url) && url.startsWith("http")){
            return true;
        }else {
            LogUtils.d("请求的地址不是正确的链接");
            return false;
        }
    }

    public static String getTextStr(TextView tv) {
        if (null != tv && null != tv.getText()) {
            return tv.getText().toString().trim();
        } else {
            return "";
        }
    }

    public static int string2int(String str) {
        int result = 0;
        try {
            result = Integer.parseInt(str
                    .trim());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static double string2Double(String str) {
        double result = -1.0;
        try {
            result = Double.valueOf(str.trim());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static boolean isEllipsis(TextView tv, int line) {
        Layout l = tv.getLayout();
        if (l != null) {
            int lines = l.getLineCount();
            LogUtils.e("isEllipsis lines = " + lines);
            if (lines >= line) {
                return true;
            }
        }
        LogUtils.e("l = null");
        return false;
    }

    /**
     * 判断多个字符串是否相等，如果其中有一个为空字符串或者null，则返回false，只有全相等才返回true
     */
    public static boolean isEquals(String... agrs) {
        String last = null;
        for (int i = 0; i < agrs.length; i++) {
            String str = agrs[i];
            if (isEmpty(str)) {
                LogUtils.e("当前的字符串为空，不做比较");
                return false;
            }
            if (last != null && !last.equals(str)) {
                LogUtils.e("当前的字符串与上个字符串比较不相等last = " + last + ", str = " + str);
                return false;
            }
            last = str;
        }
        return true;
    }

    /**
     * 返回一个高亮spannable
     *
     * @param content 文本内容
     * @param color   高亮颜色
     * @param start   起始位置
     * @param end     结束位置
     * @return 高亮spannable
     */
    public static SpannableString getHighLightText(String content, int color, int start, int end) {
        if (TextUtils.isEmpty(content)) {
            return new SpannableString("");
        }
        if (start < 0 || start > content.length() || end < 0 || end > content.length()){
            return new SpannableString(content);
        }
//        start = start >= 0 ? start : 0;
//        end = end <= content.length() ? end : content.length();
        SpannableString spannable = new SpannableString(content);
        CharacterStyle span = new ForegroundColorSpan(color);
        spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannable;
    }

    /**
     * 返回一个高亮spannable
     *
     * @param content   文本内容
     * @param matchText 要编辑的文本
     * @param color     高亮颜色
     * @return 高亮spannable
     */
    public static SpannableString getHighLightAndBindText(String content, String matchText, int color) {
        if (TextUtils.isEmpty(content)) {
            return new SpannableString("");
        }
        if (TextUtils.isEmpty(matchText)) {
            return new SpannableString(content);
        }
        if (!content.contains(matchText)) {
            return new SpannableString(content);
        }
        int start = 0, end = 0;
        start = content.indexOf(matchText);
        end = start + matchText.length();
        start = start >= 0 ? start : 0;
        end = end <= content.length() ? end : content.length();
        if (end < start) {
            return new SpannableString(content);
        }
        SpannableString spannable = new SpannableString(content);
        CharacterStyle span = new ForegroundColorSpan(color);
        spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        CharacterStyle span2 = new StyleSpan(android.graphics.Typeface.BOLD);
        spannable.setSpan(span2, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannable;
    }

    /**
     * 获取链接样式的字符串，即字符串下面有下划线
     *
     * @param resId 文字资源
     * @return 返回链接样式的字符串
     */
    public static Spanned getHtmlStyleString(int resId) {
        StringBuilder sb = new StringBuilder();
        sb.append("<a href=\"\"><u><b>").append(UIUtils.getString(resId)).append(" </b></u></a>");
        return Html.fromHtml(sb.toString());
    }

    /**
     * 格式化文件大小，不保留末尾的0
     */
    public static String formatFileSize(long len) {
        return formatFileSize(len, false);
    }

    /**
     * 格式化文件大小，保留末尾的0，达到长度一致
     */
    public static String formatFileSize(long len, boolean keepZero) {
        String size;
        DecimalFormat formatKeepTwoZero = new DecimalFormat("#.00");
        DecimalFormat formatKeepOneZero = new DecimalFormat("#.0");
        if (len < 1024) {
            size = String.valueOf(len + "B");
        } else if (len < 10 * 1024) {
            // [0, 10KB)，保留两位小数
            size = String.valueOf(len * 100 / 1024 / (float) 100) + "KB";
        } else if (len < 100 * 1024) {
            // [10KB, 100KB)，保留一位小数
            size = String.valueOf(len * 10 / 1024 / (float) 10) + "KB";
        } else if (len < 1024 * 1024) {
            // [100KB, 1MB)，个位四舍五入
            size = String.valueOf(len / 1024) + "KB";
        } else if (len < 10 * 1024 * 1024) {
            // [1MB, 10MB)，保留两位小数
            if (keepZero) {
                size = String.valueOf(formatKeepTwoZero.format(len * 100 / 1024 / 1024 / (float) 100)) + "MB";
            } else {
                size = String.valueOf(len * 100 / 1024 / 1024 / (float) 100) + "MB";
            }
        } else if (len < 100 * 1024 * 1024) {
            // [10MB, 100MB)，保留一位小数
            if (keepZero) {
                size = String.valueOf(formatKeepOneZero.format(len * 10 / 1024 / 1024 / (float) 10)) + "MB";
            } else {
                size = String.valueOf(len * 10 / 1024 / 1024 / (float) 10) + "MB";
            }
        } else if (len < 1024 * 1024 * 1024) {
            // [100MB, 1GB)，个位四舍五入
            size = String.valueOf(len / 1024 / 1024) + "MB";
        } else {
            // [1GB, ...)，保留两位小数
            size = String.valueOf(len * 100 / 1024 / 1024 / 1024 / (float) 100) + "GB";
        }
        return size;
    }

    public static int float2Int(float fnumber) {
        return Integer.valueOf(String.valueOf(fnumber));
    }

    /**
     * 手机号码格式化
     */
    public static String formatPhone(String phone) {
        if (phone.length() > 0 && phone.length() < 6) {
            return phone.charAt(0) + "*******" + phone.charAt(phone.length() - 1);
        }
        String reStr = phone.substring(phone.length() - 4, phone.length());
        String preStr = phone.substring(0, 3);
        StringBuilder sb = new StringBuilder();
        sb.append(preStr).append("*******").append(reStr);
        return sb.toString();
    }

    /**
     * 手机号码格式化
     */
    public static String formatEmail(String email) {
        int start = email.lastIndexOf("@");
        String text = email.charAt(0) + "*******" + email.substring(start, email.length());
        return text;
    }

    /**
     * 判断集合是否为空
     */
    public static boolean isListEmpty(Collection<? extends Object> list) {
        if (null == list) {
            return true;
        }
        if (list.size() == 0) {
            return true;
        }
        return false;
    }

    /**
     * 判断集合是否为空
     */
    public static boolean isMapEmpty(Map<? extends Object, ? extends Object> map) {
        if (null == map) {
            return true;
        }
        if (map.size() == 0) {
            return true;
        }
        return false;
    }

    /**
     * 实现文本复制功能
     *
     * @param content 需要被拷贝到粘贴板的文本
     */
    public static void copy(String content) {
        // 得到剪贴板管理器
        ClipboardManager cmb = (ClipboardManager) BaseApp.instance().getSystemService(Context.CLIPBOARD_SERVICE);
        cmb.setText(content.trim());
    }

    /**
     * 实现粘贴功能
     *
     * @return 需要被粘贴的文字
     */
    public static String paste() {
        // 得到剪贴板管理器
        ClipboardManager cmb = (ClipboardManager) BaseApp.instance().getSystemService(Context.CLIPBOARD_SERVICE);
        return cmb.getText().toString().trim();
    }
}
